package com.goodmr.passport.password;

import org.philcode.toolkit.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Optional;
import java.util.UUID;

/**
 * 密码数据逻辑实现
 *
 * @author <a href="mailto:bingdong13@msn.com">bigo</a>
 */
@Service
public class PasswordDaoImpl implements PasswordDao {

    private final PasswordRepository passwordRepository;

    public PasswordDaoImpl(PasswordRepository passwordRepository) {
        this.passwordRepository = passwordRepository;
    }

    /**
     * 帐号密码初始化 or 更新
     *
     * @param accountId 帐号ID
     * @param password  密码
     */
    @Override
    public void generate(long accountId, String password) {

        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

        PasswordEntity passwordEntity = new PasswordEntity();
        passwordEntity.setAccountId(accountId);
        passwordEntity.setPassword(encoder.encode(password));
        passwordEntity.setSaltHash(generateSalt());

        passwordRepository.save(passwordEntity);
    }

    /**
     * 密码校验
     *
     * @param accountId   帐号ID
     * @param rawPassword 原始密码
     * @return 原始密码与加密密码匹配，返回true，否则返回false
     */
    @Override
    public boolean verify(long accountId, String rawPassword) {

        boolean result = false;

        Optional<PasswordEntity> optional = passwordRepository.findById(accountId);

        if (optional.isPresent()) {

            PasswordEntity passwordEntity = optional.get();

            BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

            result = encoder.matches(rawPassword, passwordEntity.getPassword());
        }

        return result;
    }

    /**
     * 密码修改
     *
     * @param accountId 帐号ID
     * @param password  新密码
     */
    @Override
    public void modify(long accountId, String password) {

        passwordRepository
                .findById(accountId)
                .ifPresent(entity -> {

                    BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

                    entity.setPassword(encoder.encode(password));
                    entity.setSaltHash(generateSalt());

                    passwordRepository.save(entity);
                });
    }

    /**
     * 生成 salt 值
     *
     * @return salt 字符串
     */
    private String generateSalt() {
        return UUID.randomUUID().toString();
    }
}